/*
 * Copyright the original author or authors.
 * 
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *	  http://www.mozilla.org/MPL/MPL-1.1.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.milib.display.libraryItems.button {
	import com.googlecode.milib.display.libraryItems.MCDetectable;

	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;

	/**
	 * @author Marek Brun
	 */
	public dynamic class AbstractMCButton extends MCDetectable {
		
		private var isFreeze:Boolean;		public var isOver:Boolean=false;
		//true - the button will be not clickable during freeze
		//false - the button will be clickable during freeze 		public var isDisableAtFreeze:Boolean=true;
		//"over" - the button will go to "over" state during freeze
		//"press" - the button will go to "press" state during freeze		public var freezeAt:String='over';
		
		private var mc:MovieClip;
		
		//com.googlecode.milib.display.libraryItems.button.AbstractMCButton
		public function AbstractMCButton() {
			TextField.prototype;
			mc=MovieClip(this);
			mc.addEventListener(MouseEvent.CLICK, onMCPress, false, 0, true);
			mc.addEventListener(MouseEvent.MOUSE_DOWN, onMCMouseDown, false, 0, true);
			mc.addEventListener(MouseEvent.ROLL_OVER, onMCRollOver, false, 0, true);
			mc.addEventListener(MouseEvent.ROLL_OUT, onMCRollOut, false, 0, true);
			mc.tabEnabled=true;
			mc.useHandCursor=true;
			mc.buttonMode=true;
			mc.mouseChildren=false;
			
			//if button clip contains clip with instance name "hit" then he will become
			//automatically button clip "hitArea"
			if(mc.hit){
				mc.hitArea=mc.hit;
			}
		}
		
		/**
		 * Deactivating behave as a button.
		 */
		public function disableButtonMode():void {
			mc.useHandCursor=false;
			mc.buttonMode=false;
			mc.mouseChildren=true;
		}
		
		/**
		 * Method should implement view in rollover state
		 */
		/*abstract*/ protected function doRollOver():void {}
		
		/**
		 * Method should implement view in press state
		 */
		/*abstract*/ protected function doPress():void {}
		
		/**
		 * Method should implement view in release state
		 */
		/*abstract*/ protected function doRelease():void {}
		
		/**
		 * Method should implement view in rollout state
		 */
		/*abstract*/ protected function doRollOut():void {}
		
		/**
		 * Method can implement view in freeze state
		 */
		/*abstract*/ protected function doFreeze():void {
			if(freezeAt=='over'){
				doRollOver();
			}else if(freezeAt=='press'){
				doPress();
			}
		}
		
		/**
		 * Method can implement view after unfreeze
		 */
		/*abstract*/ protected function doUnfreeze():void {
			doRollOut();
		}
		
		/**
		 * Setting/unsetting freeze state.
		 */
		public function setIsFreeze(isFreeze:Boolean):void {
			if(isFreeze){
				freeze();
			}else{
				unfreeze();
			}
		}
		
		/**
		 * Setting freeze.
		 */
		public function freeze():void {
			if(isFreeze){ return; }
			if(isDisableAtFreeze){ disable(); }
			isFreeze=true;
			doFreeze();
		}
		
		/**
		 * Setting unfreeze.
		 */
		public function unfreeze():void {
			if(!isFreeze){ return; }
			enable();
			isFreeze=false;
			isOver=false;
			doUnfreeze();
		}
		
		/**
		 * Setting/unsetting freeze state.
		 */
		public function setIsEnabled(enabled:Boolean):void {
			if(enabled) {
				enable();
				alpha=1;
			}else{
				disable();
				alpha=0.5;
			}
		}
		
		public function disable():void {
			mc.useHandCursor=false;
			mc.mouseEnabled=false;
		}
		
		public function enable():void {
			mc.useHandCursor=true;
			mc.mouseEnabled=true;
		}
		
		/**
		 * Sets the button in rollover state
		 */
		private function setRollOver():void {
			isOver=true;
			doRollOver();
			dispatchEvent(new MCButtonEvent(MCButtonEvent.ROLLOVER, this));
		}
		
		/**
		 * Sets the button in press state
		 */
		private function setPress():void {
			doPress();
			dispatchEvent(new MCButtonEvent(MCButtonEvent.PRESS, this));
		}
		
		/**
		 * Sets the button in release state
		 */
		private function setRelease():void {
			doRelease();
			dispatchEvent(new MCButtonEvent(MCButtonEvent.RELEASE, this));
			if(this['doClick']){
				this['doClick']();
			}
		}
		
		/**
		 * Sets the button in rollout state
		 */
		private function setRollOut():void {
			isOver=false;
			if(isFreeze){
				doFreeze();
			}else{
				doRollOut();
			}
			dispatchEvent(new MCButtonEvent(MCButtonEvent.ROLLOUT, this));
		}
		
//********************************************************************************************
//		events for AbstractMCButton
//********************************************************************************************
		public function onMCRollOver(event:Event):void {
			if(isFreeze && !isDisableAtFreeze){ dispatchEvent(new MCButtonEvent(MCButtonEvent.ROLLOVER, this)); return; }
			if(isFreeze && isDisableAtFreeze){ return; }
			setRollOver();
		}
		
		public function onMCMouseDown(event:Event):void {
			if(isFreeze && !isDisableAtFreeze){ dispatchEvent(new MCButtonEvent(MCButtonEvent.PRESS, this)); return; }
			if(isFreeze && isDisableAtFreeze){ return; }
			setPress();
		}
		
		public function onMCPress(event:Event):void {
			if(isFreeze && !isDisableAtFreeze){ dispatchEvent(new MCButtonEvent(MCButtonEvent.RELEASE, this)); return; }
			if(isFreeze && isDisableAtFreeze){ return; }
			setRelease();
		}
		
		public function onMCRollOut(event:Event):void {
			if(isFreeze && !isDisableAtFreeze){ dispatchEvent(new MCButtonEvent(MCButtonEvent.ROLLOUT, this)); return; }
			if(isFreeze && isDisableAtFreeze){ return; }
			setRollOut();
		}
		
	}
}
